/*
 * 
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cmtr.h"


int idx(cmtr_matrix *mtx, int i, int j);

int idx(cmtr_matrix *mtx, int i, int j) {
	return (i * mtx->jCol + j);
}

int offset(cmtr_matrix *mtx, int i, int j);

int offset(cmtr_matrix *mtx, int i, int j) {
	return (mtx->sizeof_item * idx(mtx, i, j));
}


void cmtr_init(cmtr_matrix* mtx, int sizeof_item, int i, int j) {
   mtx->iRows = i;
   mtx->jCol = j;
   mtx->sizeof_item = sizeof_item;
   mtx->data = (void*) calloc (i*j, sizeof_item);
}


void cmtr_destroy(cmtr_matrix* mtx) {
   free(mtx->data);
   mtx->iRows = mtx->jCol = mtx->sizeof_item = 0;
}


void* cmtr_get(cmtr_matrix* mtx, int i, int j) {
   void* pret = NULL;
   pret = mtx->data + (offset(mtx, i, j));
   return pret;
}

void cmtr_set(cmtr_matrix* mtx, int i, int j, void* val) {
   void* ptrDest = mtx->data + (offset(mtx, i, j));
   bcopy(val, ptrDest, mtx->sizeof_item);
}

void cmtr_fill(cmtr_matrix* mtx, void* val) {
   int i = 0;
   int j = 0;

   for (i=0; i < mtx->iRows; i++){
      for (j=0; j < mtx->jCol; j++){
       cmtr_set(mtx , i , j , val);
      }
   }
}

void cmtr_fprintf_int(FILE* f, cmtr_matrix* mtx){
   int i = 0;
   int j = 0;

   for (i=0; i<mtx->iRows; i++) {
      for (j=0; j<mtx->jCol; j++) {
         fprintf(f, "%d\t", *(int*)cmtr_get(mtx, i, j));
      }
      fprintf(f, "\n");
   }
   fprintf(f, "Rows: %d\tColumns: %d\tElements: %d\n", mtx->iRows, mtx->jCol, mtx->iRows * mtx->jCol);
}

void cmtr_printf_int(cmtr_matrix* mtx){
   cmtr_fprintf_int(stdout, mtx);
}


void cmtr_fprintf_flt(FILE* f, cmtr_matrix* mtx){
   int i = 0;
   int j = 0;

   for (i=0; i<mtx->iRows; i++) {
      for (j=0; j<mtx->jCol; j++) {
         fprintf(f, "%.3F\t", *(float*)cmtr_get(mtx, i, j));
      }
      fprintf(f, "\n");
   }
   fprintf(f, "Rows: %d\tColumns: %d\tElements: %d\n", mtx->iRows, mtx->jCol, mtx->iRows * mtx->jCol);
}

void cmtr_printf_flt(cmtr_matrix* mtx){
   cmtr_fprintf_flt(stdout, mtx);
}


cmtr_matrix* cmtr_transp(cmtr_matrix* mtx) {
        int i = 0;
        int j = 0;
        cmtr_matrix* tmpMtx = (cmtr_matrix*)malloc(sizeof(cmtr_matrix));
        cmtr_init(tmpMtx, mtx->sizeof_item, mtx->jCol, mtx->iRows);
        for (i=0; i<mtx->iRows; i++) {
                for (j=0; j<mtx->jCol; j++) {
                        cmtr_set(tmpMtx, j, i, cmtr_get(mtx, i, j));
                }
        }
        return tmpMtx;
}


void cmtr_fprintf_transp_int(FILE* f, cmtr_matrix* mtx) {
	cmtr_matrix* ptrpMtx = cmtr_transp(mtx);
	cmtr_fprintf_int(f, ptrpMtx);
	cmtr_destroy(ptrpMtx);
}

void cmtr_printf_transp_int(cmtr_matrix* mtx) {
	cmtr_fprintf_transp_int(stdout, mtx);
}

void cmtr_fprintf_transp_flt(FILE* f, cmtr_matrix* mtx) {
	cmtr_matrix* ptrpMtx = cmtr_transp(mtx);
	cmtr_fprintf_flt(f, ptrpMtx);
	cmtr_destroy(ptrpMtx);
}

void cmtr_printf_transp_flt(cmtr_matrix* mtx) {
	cmtr_fprintf_transp_flt(stdout, mtx);
}
